/*
 * @Author: Zhou Zijian
 * @Date: 2023-03-02 00:34:17
 * @Last Modified by: Zhou Zijian
 * @Last Modified time: 2023-05-07 17:33:24
 */

#include "ConfigParser.h"
#include <fstream>

int ConfigParser::LoadJson(const std::string &json)
{
    std::ifstream f(json);
    if (!f.is_open()) {
        return ErrorCode::OPEN_FILE_FAILED;
    }
    data = nlohmann::json::parse(f);
    if (!data.contains("program") || !data.at("program").is_string()) {
        return ErrorCode::CHECK_PROGRAM_FAILED;
    }
    if (!data.contains("functions") || !data.at("functions").is_array()) {
        return ErrorCode::CHECK_FUNCTIONS_FAILED;
    }
    for (auto &element : data.at("functions")) {
        if (!element.contains("name") || !element.at("name").is_string() ||
            !element.contains("kernel") || !element.at("kernel").is_string() ||
            !element.contains("global_work_size") || !element.at("global_work_size").is_array() ||
            element.at("global_work_size").empty() ||
            !element.contains("local_work_size") || !element.at("local_work_size").is_array() ||
            (!element.at("local_work_size").empty() &&
            (element.at("local_work_size").size() != element.at("global_work_size").size()))) {
            return ErrorCode::CHECK_FUNCTION_FAILED;
        }
    }
    return 0;
}

std::string ConfigParser::GetProgram()
{
    std::string program(data.at("program"));
    return program;
}

std::vector<ConfigParser::Function> ConfigParser::GetFunctions()
{
    std::vector<ConfigParser::Function> functions;
    for (auto &element : data.at("functions")) {
        ConfigParser::Function function = {
            .name = std::string(element.at("name")),
            .kernel = std::string(element.at("kernel")),
            .globalWorkSize = element.at("global_work_size"),
            .localWorkSize = element.at("local_work_size")
        };
        functions.push_back(function);
    }
    return functions;
}

std::string ConfigParser::GetOpencl()
{
    std::string program(data.at("opencl"));
    return program;
}